﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Xml;
 
using Tao;
using Tao.OpenGl;
using Tao.Platform;
using WeifenLuo.WinFormsUI.Docking;

namespace VoltGameEditor
{
    public class functions
    {
        public static void ChangeGrid(int size)
        {
            AppSettings.General.GridSize = size;
            InvalidateViewports();
        }

        public static void InvalidateViewports()
        {
            if (mapDef.MapData.Count == 0 || mapDef.MapData.Count > (mapDef.GetDocumentIndex() + 1))
                return;
            foreach (Viewport vp in mapDef.MapData[mapDef.GetDocumentIndex()].Viewports)
                vp.Scene.Draw();
        }

        public static void DrawGrid(int gridSize, int gridLimit, Viewport.Perspectives onPerspective)
        {
            /// This function provided by Paril; modified by Skies
            int numSlices = gridLimit / gridSize; //to make sure its gridLimit X gridLimit units (was plain 16)
            int startX = -(gridLimit / 2);
            int endX = gridLimit / 2;

            Color c = AppSettings.Theming.Color_Grid;
            Gl.glBegin(Gl.GL_LINES);
            for (int x = startX, i = 0; i <= numSlices; x += gridSize, ++i)
            {
                if (i % 8 == 0) //if i = multiple of 8, make the line a lil darker.
                {
                    c = Color.FromArgb((int)(c.R / 1.25f), (int)(c.G / 1.25f), (int)(c.B / 1.25f));
                    Gl.glColor3ub(c.R, c.G, c.B);
                }
                else
                {
                    c = AppSettings.Theming.Color_Grid;
                    Gl.glColor3ub(c.R, c.G, c.B);
                }
                Point lineStart, lineEnd;
                switch (onPerspective)
                {
                    case Viewport.Perspectives.ThreeDScene:
                        {
                            lineStart = new Point(x, startX);
                            lineEnd = new Point(x, endX);

                            Gl.glVertex3i(lineStart.X, lineStart.Y, 0);
                            Gl.glVertex3i(lineEnd.X, lineEnd.Y, 0);

                            lineStart = new Point(startX, x);
                            lineEnd = new Point(endX, x);

                            Gl.glVertex3i(lineStart.X, lineStart.Y, 0);
                            Gl.glVertex3i(lineEnd.X, lineEnd.Y, 0);
                            break;
                        }
                    case Viewport.Perspectives.Top:
                        {
                            lineStart = new Point(x, startX);
                            lineEnd = new Point(x, endX);

                            Gl.glVertex3i(lineStart.X, lineStart.Y, 0);
                            Gl.glVertex3i(lineEnd.X, lineEnd.Y, 0);

                            lineStart = new Point(startX, x);
                            lineEnd = new Point(endX, x);

                            Gl.glVertex3i(lineStart.X, lineStart.Y, 0);
                            Gl.glVertex3i(lineEnd.X, lineEnd.Y, 0);
                            break;
                        }
                    case Viewport.Perspectives.Front:
                        {
                            lineStart = new Point(x, startX);
                            lineEnd = new Point(x, endX);

                            Gl.glVertex3i(lineStart.X, 0, lineStart.Y);
                            Gl.glVertex3i(lineEnd.X, 0, lineEnd.Y);

                            lineStart = new Point(startX, x);
                            lineEnd = new Point(endX, x);

                            Gl.glVertex3i(lineStart.X, 0, lineStart.Y);
                            Gl.glVertex3i(lineEnd.X, 0, lineEnd.Y);
                            break;
                        }
                    case Viewport.Perspectives.Side:
                        {
                            lineStart = new Point(x, startX);
                            lineEnd = new Point(x, endX);

                            Gl.glVertex3i(0, lineStart.X, lineStart.Y);
                            Gl.glVertex3i(0, lineEnd.X, lineEnd.Y);

                            lineStart = new Point(startX, x);
                            lineEnd = new Point(endX, x);

                            Gl.glVertex3i(0, lineStart.X, lineStart.Y);
                            Gl.glVertex3i(0, lineEnd.X, lineEnd.Y);
                            break;
                        }
                }

            }
            Gl.glEnd();


        }

        public static void StartHelp(Form sender, int type)
        {
            if (type == 0) //Help Contents
            {
                if (System.IO.File.Exists("voltGE.chm") == true)
                { Program.mainWin.help.SetShowHelp(sender, false); }
                else
                {
                    MessageBox.Show("Help file has been moved or does not exist.", "Error", MessageBoxButtons.OK);
                    Program.Console.rtb_errors.Text += "Could not start Help Contents: missing or corrupt\n";
                }
            }
            else if (type == 1) //FAQ
            {
                if (System.IO.File.Exists("vge_faq.chm") == true)
                { Program.mainWin.help.SetShowHelp(sender, true); }
                else
                {
                    MessageBox.Show("FAQ file has been moved or does not exist.", "Error", MessageBoxButtons.OK);
                    Program.Console.rtb_errors.Text += "Could not start FAQ: missing or corrupt\n";
                }
            }
        }

        public static void AssignKey(Control sender)
        {
            Button[] buttons = new Button[] { Program.Settings.button1, Program.Settings.button2, Program.Settings.button3, Program.Settings.button4, Program.Settings.button5, Program.Settings.button6, Program.Settings.button7, Program.Settings.button8, Program.Settings.button9, Program.Settings.button9 };
            bool IsMapped = false;
            Program.KeyMap.ShowDialog();

            if (Program.KeyMap.butType == keymap.ButtonType.Mouse && SettingsDiag.mea != null)
            {
                foreach (Button but in buttons)
                {
                    if (but.Text == SettingsDiag.mea.Button.ToString() && but != sender)
                    {
                        MessageBox.Show("There is already an action bound to that key.\nPlease choose another key", "Exclamation");
                        IsMapped = true;
                        break;
                    }
                }
                if (IsMapped != true)
                    sender.Text = SettingsDiag.mea.Button.ToString();
                IsMapped = false; //reset bool
            }
            else if (Program.KeyMap.butType == keymap.ButtonType.Keyboard && SettingsDiag.kea != null)
            {
                string key2 = SettingsDiag.kea.KeyCode.ToString().ToLower();
                foreach (Button but in buttons)
                {
                    if (but.Text == key2 && but != sender)
                    {
                        MessageBox.Show("There is already an action bound to that key.\nPlease choose another key", "Exclamation");
                        IsMapped = true;
                        break;
                    }
                }
                if (IsMapped != true)
                    sender.Text = key2;
                IsMapped = false; //reset bool
            }

        }

        public static void AddObjects(Globals.Game game)
        {
            Program.ObjPane.treeEnts.Nodes.Add(new TreeNodeEx("Standard Objects", 0, 0));
            Program.ObjPane.treeEnts.Nodes.Add(new TreeNodeEx("Custom Objects", 0, 0));
            switch (game)
            {
                case Globals.Game.Quake_1: //q1
                    {
                        break;
                    }
                case Globals.Game.Quake_2: //q2
                    {
                        string g = game.ToString().Replace("_", " ");
                        using (System.IO.StreamReader sr = new StreamReader("Games\\" + g + "\\Objects.list"))
                        {
                            string line = "";
                            while ((line = sr.ReadLine()) != null)
                            {

                                if (line.Contains("+"))
                                {
                                    line = line.Remove(0, 1);
                                    Program.ObjPane.treeEnts.Nodes[0].Nodes.Add(line);
                                }
                                else if (line.Contains("//") == false && line != "")
                                {
                                    string[] sa = line.Split(new char[] { '|' });
                                    int i = 0;
                                    int ci = 0;
                                    if (sa[0] == "C")
                                    {
                                        i = 1;
                                    }
                                    foreach (TreeNode n in Program.ObjPane.treeEnts.Nodes[0].Nodes)
                                    {
                                        if (sa[1] == n.Text)
                                        {
                                            ci = n.Index;
                                            break;
                                        }
                                    }
                                    TreeNodeEx node = new TreeNodeEx();
                                    IDictionary d = new Dictionary<string, string>();
                                    foreach (string item in sa[3].Split(new char[] { ';' }))
                                    {
                                        string[] sa2 = item.Split(new char[] { '=' });
                                        d[sa2[0]] = sa2[1];
                                    }
                                    node.Text = sa[2];
                                    node.DefaultKVPs = d;
                                    node.ItemType = MapObject.Type.Entity;
                                    Program.ObjPane.treeEnts.Nodes[i].Nodes[ci].Nodes.Add(node);

                                }
                            }
                        }

                        Program.ObjPane.treeEnts.Nodes[0].ExpandAll();
                        Program.ObjPane.treeEnts.SelectedNode = Program.ObjPane.treeEnts.Nodes[0];
                        break;
                    }
                case Globals.Game.Quake_III_Arena: //q3a
                    {

                        break;
                    }
            }
        }

        public static System.Boolean IsNumeric(System.Object Expression)
        {
            if (Expression == null || Expression is DateTime)
                return false;

            if (Expression is Int16 || Expression is Int32 || Expression is Int64 || Expression is Decimal || Expression is Single || Expression is Double || Expression is Boolean)
                return true;

            try
            {
                if (Expression is string)
                    Double.Parse(Expression as string);
                else
                {
                    Double.Parse(Expression.ToString());
                    return true;
                }
            }
            catch { } // just dismiss errors but return false
            return false;
        }

        public static void LaunchProgbarModal(int minCount, int maxCount, string status) //TEST
        {
            for (int i = minCount; i < maxCount; i++)
            {
                string error = Program.PbModal.UpdateProgbar(minCount, maxCount, i, status);
                if (error != null)
                    MessageBox.Show(error);
            }

        }

        public static bool Convert2Bool(CheckState state)
        {
            bool tf;
            if (state == CheckState.Checked)
                tf = true;
            else if (state == CheckState.Unchecked)
                tf = false;
            else
                return false;
            return tf;
        }
        public static bool Convert2Bool(int num)
        {
            bool tf;
            if (num == 1)
                tf = true;
            else if (num == 0)
                tf = false;
            else
                return false;
            return tf;
        }
        public static bool Convert2Bool(string str)
        {
            bool tf;
            if (str == "true" || str == "True")
                tf = true;
            else if (str == "false" || str == "False")
                tf = false;
            else
                return false;
            return tf;
        }

        public static void ShowToolboxes()
        {
            if (Program.ObjPane.IsHidden)
                Program.ObjPane.Show(Program.mainWin.dp_docs);
            //if (Program.MatBrowser.IsHidden)
            //Program.MatBrowser.Show(Program.mainWin.dp_docs);
            if (Program.Prefabs.IsHidden)
                Program.Prefabs.Show(Program.mainWin.dp_docs);
            if (Program.Console.IsHidden)
                Program.Console.Show(Program.mainWin.dp_docs);

            if (Program.ObjPane.DockState == WeifenLuo.WinFormsUI.Docking.DockState.Unknown)
                AppSettings.LoadMapSettings(Globals.GameMode);
        }
        public static void HideToolboxes()
        {
            Program.ObjPane.DockState = DockState.Unknown;
            //Program.MatBrowser.DockState = DockState.Unknown;
            Program.Prefabs.DockState = DockState.Unknown;
            Program.Console.DockState = DockState.Hidden;
        }
        public static void ChangePerspLabel(GlControl glc)
        {
            switch (glc.Perspective)
            {
                case Viewport.Perspectives.ThreeDScene:
                    glc.ViewLabel.Text = "3d View";
                    break;
                case Viewport.Perspectives.Top:
                    glc.ViewLabel.Text = "Top [ XY ]";
                    break;
                case Viewport.Perspectives.Front:
                    glc.ViewLabel.Text = "Front [ XZ ]";
                    break;
                case Viewport.Perspectives.Side:
                    glc.ViewLabel.Text = "Side [ YZ ]";
                    break;
            }
            glc.ViewLabel.BringToFront();
        }

        public static void SetupGame(Globals.Game Mode)
        {
            //Assign all the <game> labels to the specified game name...
            string game = Mode.ToString().Replace("_", " ");

            //Add any menus etc from Python files
            //Still TODO: add Python interface file...
        }
    }
}
